<template>
  <div id="swiper-box" @touchstart="touchStart"
       @touchmove="touchMove" @touchend="touchEnd">
    <div class="swiper-move">
      <slot name="swiper-imgs"></slot>
    </div>
    <div class="indicator">
      <slot name="indicator" v-if="showIndicator&&(slideCount>1)">
        <div v-for="(item,index) in slideCount"
             class="indi-item" :class="{active:index===currentIndex-1}"
             :key="index"></div>
      </slot>
    </div>
  </div>
</template>

<script>
  export default {
    name: "Swiper",
    props:{
      interval:{
        type:Number,
        default:3000,
      },
      animDuration:{
        type:Number,
        default: 300
      },
      moveRatio:{
        type:Number,
        default:0.20
      },
      showIndicator:{
        type:Boolean,
        default:true
      }
    },
    computed:{

    },
    data(){
      return {
        slideCount:0,
        totalWidth:0,
        swiperStyle:{},
        currentIndex:1,
        scrolling:false,
      }
    },
    mounted() {
      setTimeout(()=>{
        this.makeDom();
        this.startTimer();
      },50)
    },
    methods:{
      isActive(index){
        return index===this.currentIndex-1
      },
      startTimer(){
        this.playTimer=window.setInterval(()=>{
          this.currentIndex++;
          this.scrollContent(-this.currentIndex*this.totalWidth);
        },this.interval)
      },
      stopTimer(){
        window.clearInterval(this.playTimer);
      },
      scrollContent(currentPosition){
        this.scrolling=true;
        this.swiperStyle.transition=this.animDuration+'ms';
        this.setTransform(currentPosition);
        this.checkPosition();
        this.scrolling=false;
      },
      checkPosition(){
        window.setTimeout(()=>{
          this.swiperStyle.transition='0ms';
          if(this.currentIndex>=this.slideCount+1){
            this.currentIndex=1;
            this.setTransform(-this.currentIndex*this.totalWidth);
          }else if(this.currentIndex<1){
            this.currentIndex=this.slideCount;
            this.setTransform(-this.currentIndex*this.totalWidth);
          }
          this.$emit('transitionEnd',this.currentIndex-1);
        },this.animDuration)
      },
      makeDom(){
        let srEl=document.getElementsByClassName('swiper-move')[0];
        let sliEls=srEl.getElementsByClassName('slide');
        this.slideCount=sliEls.length;
        if(this.slideCount>1){
          let cloneF=sliEls[0].cloneNode(true);
          let cloneL=sliEls[this.slideCount-1].cloneNode(true);
          srEl.insertBefore(cloneL,sliEls[0]);
          srEl.appendChild(cloneF);
          this.totalWidth=srEl.offsetWidth;
          this.swiperStyle=srEl.style;
        }
        this.setTransform(-this.totalWidth);
      },
      setTransform(position){
        this.swiperStyle.transform=`translate3d(${position}px,0,0)`;
        this.swiperStyle[`-webkit-transform`]=`translate3d(${position}px,0,0)`;
        this.swiperStyle[`-ms-transform`]=`translate3d(${position}px,0,0)`;
      },

      touchStart(e){
        if(this.scrolling)return;
        this.stopTimer();
        this.startx=e.touches[0].pageX;
      },
      touchMove(e){
        this.currentx=e.touches[0].pageX;
        this.distance=this.currentx-this.startx;
        let currentPosition=-this.currentIndex*this.totalWidth;
        let moveDistance=this.distance+currentPosition;
        this.setTransform(moveDistance);
      },
      touchEnd(e){
        let currentMove=Math.abs(this.distance);
        if(this.distance===0){
          return
        }else if(this.distance>0&&currentMove>this.totalWidth*this.moveRatio){
          this.currentIndex--;
        }else if(this.distance<0&&currentMove>this.totalWidth*this.moveRatio){
          this.currentIndex++;
        }
        this.scrollContent(-this.currentIndex*this.totalWidth);
        this.startTimer();
      },
    },
  }
</script>

<style scoped>
  #swiper-box{
    width: 100%;
    overflow: hidden;
    position: relative;
  }
  .swiper-move{
    display: flex;
  }
  .indicator{
    display: flex;
    justify-content: center;
    position: absolute;
    width: 100%;
    bottom: 8px;
  }
  .indi-item{
    box-sizing: border-box;
    width: 8px;
    height: 8px;
    border-radius: 4px;
    background-color: #fff;
    line-height: 8px;
    text-align: center;
    font-size: 12px;
    margin: 0 5px;
  }
  .indi-item.active{
    background-color: rgba(212,62,46,1);
  }
</style>
